package com.cskaoyan.aspect;

import com.cskaoyan.bean.vo.BaseRespVo;
import com.cskaoyan.bean.admin.Admin;
import com.cskaoyan.bean.adminLog.Log;
import com.cskaoyan.mapper.LogMapper;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.aspectj.lang.annotation.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import org.apache.commons.lang.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * 记录操作日志
 */

@Aspect
@Component
public class LogAspect {
    private static final Map<String, String> actionMap = new HashMap<>();

    static {
        actionMap.put("/admin/auth/login","登录");
        actionMap.put("/admin/auth/logout", "退出");
        actionMap.put("/admin/admin/create", "创建管理员");
        actionMap.put("/admin/admin/update", "编辑管理员");
        actionMap.put("/admin/admin/delete", "删除管理员");
        //actionMap.put("/admin/order/ship", "订单发货");
    }

    private Log log;

    @Autowired
    LogMapper logMapper;

    @Pointcut("@annotation(com.cskaoyan.aspect.OperationLog)")
    public void customPoint(){}

    @Before("customPoint()")
    public void logBefore(){
        log = new Log();
        Subject subject = SecurityUtils.getSubject();
        Admin principal = (Admin) subject.getPrincipal();
        if (principal != null) {
            log.setAdmin(principal.getUsername());
        }
    }

    @AfterReturning(value = "customPoint()", returning = "returnValue")
    public void logAfterReturning(Object returnValue){
        BaseRespVo result = (BaseRespVo) returnValue;
        if (result.getErrno() == 0) {
            log.setStatus(true);
        }else {
            log.setStatus(false);
        }
        log.setResult(result.getErrmsg());
    }

    @After("customPoint()")
    public void logAfter(){
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder
                .getRequestAttributes();
        HttpServletRequest request = requestAttributes.getRequest();
        String ip = getIpAddress(request);
        log.setIp(ip);

        String requestURI = request.getRequestURI();
        String action = actionMap.get(requestURI);
        log.setAction(action);
        if (("登录".equals(action) || "退出".equals(action)) && log.getStatus()) {
            log.setResult(null);
        }

        if ("登录".equals(action)) {
            Subject subject = SecurityUtils.getSubject();
            Admin principal = (Admin) subject.getPrincipal();
            if (principal == null) {
                log.setAdmin("匿名用户");
            }else {
                log.setAdmin(principal.getUsername());
            }
        }

        Date date = new Date();
        log.setAddTime(date);
        log.setUpdateTime(date);
        log.setType(1);
        log.setDeleted(false);

        logMapper.insert(log);
    }


    private String getIpAddress(HttpServletRequest request) {
        String ip = request.getHeader("X-Forwarded-For");
        if (StringUtils.isNotEmpty(ip) && !"unKnown".equalsIgnoreCase(ip)) {
            //多次反向代理后会有多个ip值，第一个ip才是真实ip
            int index = ip.indexOf(",");
            if (index != -1) {
                return ip.substring(0, index);
            } else {
                return ip;
            }
        }
        ip = request.getHeader("X-Real-IP");
        if (StringUtils.isNotEmpty(ip) && !"unKnown".equalsIgnoreCase(ip)) {
            return ip;
        }
        return request.getRemoteAddr();
    }


}
